package commEntityManager

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisService"
	"gitee.com/fierce_wolf/go-fox-edge-common/commSql"
	"time"
)

var (
	EntityManager *entityManager
)

type entityManager struct {
	Initialized bool
	SourceTypes map[string]interface{} // 需要数据库和redis之间进行同步的数据源类型
}

func init() {
	EntityManager = &entityManager{}
	EntityManager.Initialized = false
	EntityManager.SourceTypes = make(map[string]interface{})
}

func InitLoadEntity() {
	for !EntityManager.Initialized {
		// 没有初始化成功，那么等一会，再来一次上述操作
		initialized := true

		initialized = initialized && EntityManager.InitLoadEntity()
		if !initialized {
			time.Sleep(3000)
		} else {
			EntityManager.Initialized = true
		}
	}
}

// Scheduler 创建一个线程
func Scheduler() {
	go scheduler()
}

// 线程函数
func scheduler() {
	for true {
		time.Sleep(1 * time.Second)

		EntityManager.SyncEntity()
	}
}

func InsertEntity(entity commEntity.IEntity) error {
	if commSql.HasSchema(entity.Type()) {
		err := commSql.InsertEntity(entity)
		if err != nil {
			return err
		}
	}

	commRedisService.InsertEntity(entity)
	return nil
}

func UpdateEntity(entity commEntity.IEntity) error {
	if commSql.HasSchema(entity.Type()) {
		err := commSql.UpdateEntityById(entity)
		if err != nil {
			return err
		}
	}

	commRedisService.UpdateEntity(entity)
	return nil
}

func DeleteEntity(entity commEntity.IEntity) error {
	if commSql.HasSchema(entity.Type()) {
		err := commSql.DeleteEntityById(entity.Type(), entity.GetBaseEntity().Id)
		if err != nil {
			return err
		}
	}

	commRedisService.DeleteEntity(entity.Type(), entity.MakeServiceKey())
	return nil
}

func GetEntityById(entityType string, id int64) commEntity.IEntity {
	return commRedisService.GetEntityById(entityType, id)
}

func GetEntityByServiceKey(entityType string, serviceKey string) (commEntity.IEntity, error) {
	return commRedisService.GetEntityByServiceKey(entityType, serviceKey)
}

func GetEntityByServiceKeys(entityType string, serviceKeys []string) (map[string]commEntity.IEntity, error) {
	return commRedisService.GetEntityByServiceKeys(entityType, serviceKeys)
}

func FindEntityList(entityType string, finder func(entity commEntity.IEntity) bool) []commEntity.IEntity {
	return commRedisService.FindEntityList(entityType, finder)
}

func FindEntity(entityType string, finder func(entity commEntity.IEntity) bool) commEntity.IEntity {
	return commRedisService.FindEntity(entityType, finder)
}

func GetEntityCount(entityType string, finder func(entity commEntity.IEntity) bool) (int, error) {
	return commRedisService.GetEntityCount(entityType, finder)
}

func GetEntityMap(entityType string) (map[string]commEntity.IEntity, error) {
	return commRedisService.GetEntityMap(entityType)
}

func GetAgileService(entityType string) *commRedisService.RedisAgileService {
	return commRedisService.GetAgileService(entityType)
}
